package com.ruoyi.business.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import com.ruoyi.business.config.WebhookWechatConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ruoyi.business.domain.BusinessInfo;
import com.ruoyi.business.domain.BusinessMessage;
import com.ruoyi.business.domain.BusinessReminder;
import com.ruoyi.business.mapper.BusinessInfoMapper;
import com.ruoyi.business.mapper.BusinessMessageMapper;
import com.ruoyi.business.mapper.BusinessReminderMapper;
import com.ruoyi.business.service.IBusinessInfoService;
import com.ruoyi.business.service.IBusinessReminderService;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.DateUtils;
import org.apache.commons.lang3.StringUtils;

/**
 * 提醒管理 服务层实现
 *
 * @author ruoyi
 */
@Service
public class BusinessReminderServiceImpl implements IBusinessReminderService {
    private static final Logger log = LoggerFactory.getLogger(BusinessReminderServiceImpl.class);

    @Autowired
    private BusinessReminderMapper businessReminderMapper;

    @Autowired
    private BusinessInfoMapper businessInfoMapper;

    @Autowired
    private BusinessMessageMapper businessMessageMapper;
    @Autowired
    private WeChatWorkNotificationService weChatWorkNotificationService;

    @Autowired
    private WebhookWechatConfig webhookWechatConfig;

    /**
     * 查询提醒信息
     *
     * @param reminderId 提醒ID
     * @return 提醒信息
     */
    @Override
    public BusinessReminder selectBusinessReminderById(Long reminderId) {
        return businessReminderMapper.selectBusinessReminderById(reminderId);
    }

    /**
     * 查询提醒列表
     *
     * @param businessReminder 提醒信息
     * @return 提醒集合
     */
    @Override
    public List<BusinessReminder> selectBusinessReminderList(BusinessReminder businessReminder) {
        return businessReminderMapper.selectBusinessReminderList(businessReminder);
    }

    /**
     * 新增提醒
     *
     * @param businessReminder 提醒信息
     * @return 结果
     */
    @Override
    public int insertBusinessReminder(BusinessReminder businessReminder) {
        businessReminder.setCreateTime(DateUtils.getNowDate());
        return businessReminderMapper.insertBusinessReminder(businessReminder);
    }

    /**
     * 修改提醒
     *
     * @param businessReminder 提醒信息
     * @return 结果
     */
    @Override
    public int updateBusinessReminder(BusinessReminder businessReminder) {
        businessReminder.setUpdateTime(DateUtils.getNowDate());
        return businessReminderMapper.updateBusinessReminder(businessReminder);
    }

    /**
     * 删除提醒对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteBusinessReminderByIds(String ids) {
        return businessReminderMapper.deleteBusinessReminderByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除提醒信息
     *
     * @param reminderId 提醒ID
     * @return 结果
     */
    @Override
    public int deleteBusinessReminderById(Long reminderId) {
        return businessReminderMapper.deleteBusinessReminderById(reminderId);
    }

    /**
     * 取消提醒
     *
     * @param reminderId 提醒ID
     * @return 结果
     */
    @Override
    public int cancelReminder(Long reminderId) {
        BusinessReminder reminder = new BusinessReminder();
        reminder.setReminderId(reminderId);
        reminder.setStatus("3"); // 已取消
        reminder.setUpdateTime(DateUtils.getNowDate());
        return businessReminderMapper.updateReminderStatus(reminder);
    }

    /**
     * 手动触发发送提醒任务
     *
     * @param reminderId 提醒ID
     * @return 结果
     */
    @Override
    public int triggerSendReminder(Long reminderId) {
        // 查询提醒任务
        BusinessReminder reminder = businessReminderMapper.selectBusinessReminderById(reminderId);
        if (reminder == null || !"0".equals(reminder.getRecordType())) {
            return 0;
        }

        log.info("手动触发发送提醒，提醒ID:{}", reminderId);

        // 发送提醒消息
        boolean sendResult = sendByChannel(reminder);

        // 更新提醒状态
        BusinessReminder updateReminder = new BusinessReminder();
        updateReminder.setReminderId(reminderId);
        updateReminder.setSendTime(new Date());

        if (sendResult) {
            updateReminder.setStatus("1"); // 已发送
        } else {
            updateReminder.setStatus("2"); // 发送失败
            updateReminder.setRetryCount(reminder.getRetryCount() + 1);
        }

        // 将任务转为记录
        return businessReminderMapper.updateReminderTaskToRecord(updateReminder);
    }

    @Override
    public String sendRemindersWithoutCondition(String reminderId) {
        log.info("开始执行无条件发送提醒任务...");
        Long rid = Long.valueOf(reminderId);
        BusinessReminder reminder = businessReminderMapper.selectBusinessReminderById(rid);
        log.info("处理提醒ID:{}, 手机:{}, 内容:{}",
                reminder.getReminderId(),
                reminder.getMobilePhone(),
                reminder.getContent());

        // 根据渠道选择发送方式
        boolean sendResult = sendByChannel(reminder);
        return "";
    }

    /**
     * 发送提醒消息
     */
    @Override
    public int sendReminders() {
        log.info("开始执行提醒发送任务...");

        // 查询待发送的提醒任务
        List<BusinessReminder> reminderList = businessReminderMapper.selectReminderTaskList();

        if (reminderList == null || reminderList.isEmpty()) {
            log.info("没有待发送的提醒任务");
            return 0;
        }

        log.info("找到{}个待发送的提醒任务", reminderList.size());

        // 批次号使用当前时间
        String batchNo = DateUtils.dateTimeNow();
        int successCount = 0;

        // 逐个处理提醒任务
        for (BusinessReminder reminder : reminderList) {
            try {
                // 检查计划发送时间是否已到
                if (reminder.getPlanSendTime().after(new Date())) {
                    log.info("提醒ID:{} 的计划发送时间未到，跳过", reminder.getReminderId());
                    continue;
                }

                log.info("处理提醒ID:{}, 手机:{}, 内容:{}",
                        reminder.getReminderId(),
                        reminder.getMobilePhone(),
                        reminder.getContent());

                // 根据渠道选择发送方式
                boolean sendResult = sendByChannel(reminder);

                // 更新提醒状态
                updateReminderStatus(reminder, sendResult, batchNo);

                if (sendResult) {
                    successCount++;
                }
            } catch (Exception e) {
                log.error("处理提醒ID:{}失败", reminder.getReminderId(), e);
                // 更新为发送失败状态
                updateReminderStatus(reminder, false, batchNo);
            }
        }

        log.info("提醒发送任务执行完毕，成功发送: {}", successCount);
        return successCount;
    }

    /**
     * 根据渠道发送提醒
     *
     * @param reminder 提醒信息
     * @return 发送结果
     */
    private boolean sendByChannel(BusinessReminder reminder) {
        String channel = reminder.getChannel();
        boolean result = false;

        // 记录消息日志
        BusinessMessage message = new BusinessMessage();
        message.setReminderId(reminder.getReminderId());
        message.setMobilePhone(reminder.getMobilePhone());
        message.setUserName(reminder.getUserName());
        message.setContent(reminder.getContent());
        message.setSendTime(new Date());
        message.setBatchNo(DateUtils.dateTimeNow());
        message.setRetryCount(0);
        message.setCreateBy("system");

        try {
            // 根据渠道选择发送方式
            switch (channel) {
                case "0": // 企业微信
                    result = sendWechatMessage(reminder);
                    message.setMessageType("2"); // 微信消息
                    break;

                case "1": // 短信
                    result = sendSmsMessage(reminder);
                    message.setMessageType("1"); // 短信消息
                    break;

                case "2": // 两者同时
                    boolean wechatResult = sendWechatMessage(reminder);
                    boolean smsResult = sendSmsMessage(reminder);
                    result = wechatResult && smsResult; // 两者都成功才算成功
                    message.setMessageType("1"); // 以短信为主
                    break;

                default:
                    log.warn("未知的提醒渠道:{}", channel);
                    break;
            }

            // 设置发送状态
            message.setStatus(result ? "1" : "2"); // 1:成功 2:失败
            if (!result) {
                message.setFailReason("发送失败");
            }

        } catch (Exception e) {
            log.error("发送提醒失败", e);
            message.setStatus("2"); // 失败
            message.setFailReason(e.getMessage());
            result = false;
        }

        // 记录消息日志
        businessMessageMapper.insertBusinessMessage(message);

        return result;
    }

    /**
     * 发送微信消息
     *
     * @param reminder 提醒信息
     * @return 发送结果
     */
    private boolean sendWechatMessage(BusinessReminder reminder) {
        log.info("发送企业微信消息: {}", reminder.getMobilePhone());
        weChatWorkNotificationService.sendReminder(reminder);
        return true;
    }

    /**
     * 发送短信消息
     *
     * @param reminder 提醒信息
     * @return 发送结果
     */
    private boolean sendSmsMessage(BusinessReminder reminder) {
        log.info("发送短信消息: {}", reminder.getMobilePhone());
        // TODO: 实际对接短信平台API进行发送
        return true;
    }

    /**
     * 更新提醒状态
     *
     * @param reminder 提醒信息
     * @param success  是否成功
     * @param batchNo  批次号
     */
    private void updateReminderStatus(BusinessReminder reminder, boolean success, String batchNo) {
        // 更新提醒状态
        BusinessReminder updateReminder = new BusinessReminder();
        updateReminder.setReminderId(reminder.getReminderId());
        updateReminder.setSendTime(new Date());

        if (success) {
            updateReminder.setStatus("1"); // 已发送
        } else {
            updateReminder.setStatus("2"); // 发送失败
            updateReminder.setRetryCount(reminder.getRetryCount() + 1);
        }

        // 将任务转为记录
        businessReminderMapper.updateReminderTaskToRecord(updateReminder);
    }

    /**
     * 扫描即将到期业务并创建提醒任务
     */
    @Override
    public int scanExpiringBusiness() {
        // 获取当前日期
        Date now = DateUtils.getNowDate();

        // 获取3天后的日期（到期提醒阈值）
        Date expirationThreshold = DateUtils.addDays(now, 3);

        log.info("开始扫描即将到期业务，扫描范围：{} 至 {}",
                DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, now),
                DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, expirationThreshold));

        // 查询即将到期的业务列表（3天内到期）
        List<BusinessInfo> expiringBusinessList = businessInfoMapper.selectExpiringBusinessList(now, expirationThreshold);

        if (expiringBusinessList == null || expiringBusinessList.isEmpty()) {
            log.info("没有找到即将到期的业务");
            return 0;
        }

        log.info("找到{}个即将到期的业务", expiringBusinessList.size());

        int createdCount = 0;

        for (BusinessInfo business : expiringBusinessList) {
            // 检查是否已存在相同业务的未发送提醒
            if (!hasExistingReminder(business.getBusinessId())) {
                // 创建到期提醒任务
                boolean created = createExpirationReminder(business);
                if (created) {
                    createdCount++;
                }
            } else {
                log.info("业务ID:{}已存在未发送提醒，跳过", business.getBusinessId());
            }
        }

        log.info("扫描完成，共创建{}个提醒任务", createdCount);
        return createdCount;
    }

    /**
     * 检查是否已存在相同业务的未发送提醒
     *
     * @param businessId 业务ID
     * @return 是否存在
     */
    private boolean hasExistingReminder(Long businessId) {
        return businessReminderMapper.checkExistingReminder(businessId) > 0;
    }

    /**
     * 创建到期提醒任务
     *
     * @param business 业务信息
     * @return 是否创建成功
     */
    private boolean createExpirationReminder(BusinessInfo business) {
        try {
            BusinessReminder reminder = new BusinessReminder();
            reminder.setBusinessId(business.getBusinessId());
            reminder.setMobilePhone(business.getMobilePhone());
            reminder.setUserName(business.getUserName());
            reminder.setBusinessName(business.getBusinessName());
            reminder.setBusinessType(business.getBusinessType());
            reminder.setEndTime(business.getEndTime());

            // 设置为到期提醒类型
            reminder.setReminderType("1"); // 1:到期提醒

            // 默认使用短信渠道
            reminder.setChannel("1"); // 1:短信

            // 设置为任务类型，待发送状态
            reminder.setRecordType("0"); // 0:任务
            reminder.setStatus("0");     // 0:待发送

            // 设置来源为系统自动
            reminder.setSourceType("0"); // 0:系统自动

            // 设置计划发送时间为当前时间
            reminder.setPlanSendTime(DateUtils.getNowDate());

            // 设置提醒内容
            String content = generateReminderContent(business);
            reminder.setContent(content);

            // 批次号使用日期时间
            reminder.setBatchNo(DateUtils.dateTimeNow());

            // 初始重试次数为0
            reminder.setRetryCount(0);

            // 设置创建者为system
            reminder.setCreateBy("system");

            // 插入提醒记录
            businessReminderMapper.insertBusinessReminder(reminder);

            log.info("成功创建提醒任务，业务ID:{}, 提醒内容:{}", business.getBusinessId(), content);
            return true;
        } catch (Exception e) {
            log.error("创建提醒任务失败，业务ID:{}", business.getBusinessId(), e);
            return false;
        }
    }

    /**
     * 生成提醒内容
     *
     * @param business 业务信息
     * @return 提醒内容
     */
    private String generateReminderContent(BusinessInfo business) {
        String endTimeStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, business.getEndTime());
        return String.format("尊敬的%s用户，您的%s业务将于%s到期，请及时续费以避免服务中断。",
                business.getUserName(), business.getBusinessName(), endTimeStr);
    }

    /**
     * 导入提醒数据
     *
     * @param reminderList  提醒数据列表
     * @param updateSupport 是否更新支持，如果已存在，则进行更新数据
     * @param operName      操作用户
     * @return 结果
     */
    @Override
    public String importReminder(List<BusinessReminder> reminderList, boolean updateSupport, String operName) {
        if (reminderList == null || reminderList.isEmpty()) {
            throw new RuntimeException("导入提醒数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        String batchNo = DateUtils.dateTimeNow(); // 使用当前时间作为批次号

        for (BusinessReminder reminder : reminderList) {
            try {
                // 验证必填项
                validateReminder(reminder);

                // 设置默认值
                setDefaultValues(reminder, operName, batchNo);

                // 执行插入
                businessReminderMapper.insertBusinessReminder(reminder);
                successNum++;

                successMsg.append("<br/>" + successNum + "、手机号 " + reminder.getMobilePhone() + " 导入成功");
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、手机号 " + reminder.getMobilePhone() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }

        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new RuntimeException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 校验提醒数据
     *
     * @param reminder 提醒数据
     */
    private void validateReminder(BusinessReminder reminder) {
        if (StringUtils.isEmpty(reminder.getMobilePhone())) {
            throw new RuntimeException("手机号码不能为空");
        }

        if (StringUtils.isEmpty(reminder.getBusinessName())) {
            throw new RuntimeException("业务名称不能为空");
        }
    }

    /**
     * 设置提醒默认值
     *
     * @param reminder 提醒数据
     * @param operName 操作人
     * @param batchNo  批次号
     */
    private void setDefaultValues(BusinessReminder reminder, String operName, String batchNo) {
        // 设置来源为Excel导入
        reminder.setSourceType("2");

        // 默认为任务类型，待发送
        if (StringUtils.isEmpty(reminder.getRecordType())) {
            reminder.setRecordType("0");
        }

        // 默认状态为待发送
        if (StringUtils.isEmpty(reminder.getStatus())) {
            reminder.setStatus("0");
        }

        // 默认为到期提醒
        if (StringUtils.isEmpty(reminder.getReminderType())) {
            reminder.setReminderType("1");
        }

        // 默认渠道为短信
        if (StringUtils.isEmpty(reminder.getChannel())) {
            reminder.setChannel("1");
        }

        // 设置默认的计划发送时间
        if (reminder.getPlanSendTime() == null) {
            reminder.setPlanSendTime(DateUtils.getNowDate());
        }

        // 设置重试次数默认为0
        if (reminder.getRetryCount() == null) {
            reminder.setRetryCount(0);
        }

        // 设置批次号
        reminder.setBatchNo(batchNo);

        // 设置创建者
        reminder.setCreateBy(operName);

        // 设置创建时间
        reminder.setCreateTime(DateUtils.getNowDate());
    }
} 